### Классы MarcRecord, RecordField и SubField

#### MarcRecord

Каждый экземпляр класса `MarcRecord` соответствует одной записи в базе данных ИРБИС. Он содержит следующие поля:

Поле     | Тип                      | Назначение
---------|--------------------------|----------
mfn      | unsigned int             | Номер записи в мастер-файле. Для вновь созданных записей 0
status   | unsigned int             | Статус записи: логически удалена, отсутствует (см. ниже)
version  | unsigned int             | Номер версии записи
fields   | std::list\<RecordField\> | Список полей записи
database | std::wstring             | Имя базы данных, из которой загружена данная запись. Для вновь созданных записей пустая строка

Статус записи: набор флагов (определены как `enum RecordStatus`)

Имя                | Число | Значение
-------------------|-------|---------
LogicallyDeleted   | 1     | Логически удалена (может быть восстановлена)
PhysicallyDeleted  | 2     | Физически удалена (не может быть восстановлена)
Absent             | 4     | Отсутствует
NonActualized      | 8     | Не актуализирована
Last               | 32    | Последняя версия записи
Locked             | 64    | Запись заблокирована на ввод

**add(int tag, const std::wstring &value=L"")** -- добавляет в конец записи поле с указанными меткой и значением. Возвращает добавленное поле, поэтому может использоваться для "цепочечных" вызовов методов, добавляющих подполя в это поле (см. пример ниже).

**clear()** -- очищает запись (удаляет все поля). Возвращает `this`.

**decode(const StringList &lines)** -- декодирование записи из протокольного представления.

**encode(const std::wstring &delimiter)** -- кодирование записи в протокольное представление.

**fm(int tag, wchar_t code=L'\0')** -- получение значения поля (или подполя, если задан `code`) с указанной меткой. Если поле (или подполе) не найдено, возвращает `nullptr`.

**fma(int tag, wchar_t code=L'\0')** -- получение массива значений полей (или подполей, если задан `code`) с указанной меткой. Если поля (или подполя) не найдены, возвращает пустой массив.

**getField(int tag, int occurrence=0)** -- получение поля с указанной меткой (с учётом повторения). Если поле не найдено, возвращает `nullptr`.

**getFields(int tag)** -- получение массива полей с указанной меткой. Если поля не найдены, возвращается пустой массив.

**insertAt(int index, const RecordField &field)** -- вставка поля в указанную позицию.

**bool deleted()** -- проверка статуса, не удалена ли запись.

**removeAt(int index)** -- удаление поля по указанному индексу.

**removeField(int tag)** -- удаление всех полей с указанной меткой.

**reset()** -- сброс состояния записи, отвязка её от базы данных. Поля данных остаются при этом нетронутыми. Возвращает `$this`.

**verify(bool throwOnError=true)** -- проверяет, правильно ли сформирована запись (и все её подполя). При обнаружении ошибки бросает исключение, если `throwOnError==true`.

Конструирование с помощью метода `add`:

```c++
irbis::MarcRecord record;
record.add (700)
    .add ('a', L"Миронов")
    .add ('b', L"А. В.")
    .add ('g', L"Алексей Владимирович");
record.add (200)
    add(L'a', L"Заглавие книги");    
```

Конструирование с помощью списка инициализации:

```c++
irbis::MarcRecord record ({
    { 700, { { 'a', L"Миронов" }, 
             { 'b', L"А. В." },  
             { 'g', L"Алексей Владимирович" } } },
    { 200, { { 'a', L"Заглавие книги" } } }    
});
```

Конструирование с помощью оператора `<<`:

```c++
irbis::MarcRecord record;
record << 700 // Добавляем поле с меткой 700 
    << 'a' << L"Миронов"
    << 'b' << L"А. В."
    << 'g' << L"Алексей Владимирович"
    << 200 // Добавляем поле с меткой 200
    << 'a' << L"Заглавие книги";
```

#### RecordField

Поле|Тип|Назначение
----------|---|----------
tag       | int                   | Метка поля
value     | std::wstring          | Значение поля до первого разделителя
subfields | std::list\<SubField\> | Массив подполей

**add(wchar_t code, const std::wstring &value)** -- добавляет подполе с указанными кодом и значением к полю. Возвращает `this`, так что может испольоваться для "цепочечных" вызовов.

**clear()** -- очищает поле (удаляет значение и все подполя). Возвращает `this`.

**decode(const StringList &lines)** -- декодирование поля из протокольного представления.

**getEmbeddedFields()** -- получает массив встроенных полей из данного поля.

**getFirstSubfield(wchar_t code)** -- возвращает первое вхождение подполя с указанным кодом или `nullptr`.

**getFirstSubfieldValue(wchar_t code)** -- возвращает значение первого вхождения подполя с указанным кодом или пустую строку.

**insertAt(int index, const SubField &subfield)** -- вставка подполя в указанную позицию.
 
**removeAt(int index)** -- удаление подполя по указанному индексу.

**removeSubfield(wchar_t code)** -- удаление всех подполей с указанным кодом.

**verify(bool throwOnError)** -- проверяет, правильно ли сформировано поле (и все его подполя). При обнаружении ошибки бросает исключение, если `throwOnError==true`.

Конструирование с помощью метода `add`:

```c++
irbis::RecordField field { 700 };
field.add ('a', L"Миронов")
    .add ('b', L"А. В.")
    .add ('g', L"Алексей Владимирович");
```

Конструирование с помощью списка инициализации:

```c++
irbis::RecordField { 700, { 
    { 'a', L"Миронов" },
    { 'b', L"А. В." },
    { 'g', L"Алексей Владимирович" }
}};
```

Конструирование с помощью операторов `"" _field` и `<<`:

```c++
irbis::RecordField field = 700_field 
    << ('a'_sub << L"Миронов") 
    << ('b'_sub << L"А. В.")
    << ('g'_sub << L"Алексей Владимирович");
```

#### SubField

Поле  | Тип          | Назначение
------|--------------|----------
code  | wchar_t      | Код подполя.
value | std::wstring | Значение подполя.

**verify(bool throwOnError)** -- проверяет, правильно ли сформировано подполе. При обнаружении ошибки бросает исключение, если `throwOnError==true`.

Конструирование с помощью обычного конструктора:

```c++
irbis::SubField subfield ('a', L"Value");
```

Конструирование с помощью операторов `"" _sub` и `<<`:

```c++
irbis::SubField subfield = 'a'_sub << L"Value";
```

#### RawRecord

Запись с нераскодированными полями/подполями.

Поле     | Тип          | Назначение
---------|--------------|----------
database | std:wstring  | Имя базы данных, из которой загружена данная запись. Для вновь созданных записей пустая строка
mfn      | unsigned int | Номер записи в мастер-файле. Для вновь созданных записей 0
status   | unsigned int | Статус записи: логически удалена, отсутствует (см. ниже)
version  | unsigned int | Номер версии записи
fields   | StringList   | Список полей записи в "сыром" виде

[Предыдущая глава](chapter2.md) | [Следующая глава](chapter3.md)
